#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h> 
#include <sys/stat.h>
#include <sys/types.h>
#include <semaphore.h>
#include <pthread.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "cJSON.h"

// 定义结构体表示消息头和能源值
struct head {
    int type;
    char mean[10];
};

struct energy_value {
    float water;
    float battery;
    float gas;
};

// 界面函数，输出操作菜单
void center() {
    printf("\t\t\t----------------------------\t\t\t\n");
    printf("\t\t\t-------1. 水    表----------\t\t\t\n");
    printf("\t\t\t-------2. 电    表----------\t\t\t\n");
    printf("\t\t\t-------3. 天然气表----------\t\t\t\n");
    printf("\t\t\t-------4. 退    出----------\t\t\t\n");
    printf("\t\t\t----------------------------\t\t\t\n");
}

int main(int argc, const char* argv[]) {
    int sock = 0;
    struct sockaddr_in seraddr;
    memset(&seraddr, 0, sizeof(struct sockaddr_in));
    seraddr.sin_family = AF_INET;
    seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    seraddr.sin_port = htons(6867);

    // 创建套接字
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
        perror("socket");
        exit(-1);
    }

    // 连接服务器
    int ret = 0;
    ret = connect(sock, (struct sockaddr*)&seraddr, sizeof(struct sockaddr));
    if (ret == -1) {
        perror("connect");
        close(sock);
        exit(-1);
    }

    int sel = 0;
    char type[20] = {0};
    struct head hd;
    memset(&hd, 0, sizeof(hd));
    cJSON *json = NULL;

    while (1) {
        center();
        printf("输入您的选择：");
        scanf("%d", &sel);

        switch (sel) {
            case 1:
                hd.type = 1;  // 假设1表示水表，根据实际服务器约定调整
                strcpy(hd.mean, "water");
                break;
            case 2:
                hd.type = 2;  // 假设2表示电表，根据实际服务器约定调整
                strcpy(hd.mean, "elect");
                break;
            case 3:
                hd.type = 3;  // 假设3表示天然气表，根据实际服务器约定调整
                strcpy(hd.mean, "gas");
                break;
            case 4:
                close(sock);
                return 0;
            default:
                printf("错误的输入\n");
                continue;
        }

        struct energy_value val;
        memset(&val, 0, sizeof(val));
        for (int i = 0; i < 100; i++) {
            val.water = 32.22 + i;
            val.battery = 19.19 + 0.5 * i;
            val.gas = 75.67 + 0.2 * i;

            // 创建JSON对象并添加相关字段
            json = cJSON_CreateObject();
            cJSON_AddItemToObject(json, "type", cJSON_CreateNumber(hd.type));
            cJSON_AddItemToObject(json, "water", cJSON_CreateNumber(val.water));
            cJSON_AddItemToObject(json, "battery", cJSON_CreateNumber(val.battery));
            cJSON_AddItemToObject(json, "gas", cJSON_CreateNumber(val.gas));

            char *buf = cJSON_Print(json);
            if (buf == NULL) {
                perror("JSON print error");
                cJSON_Delete(json);
                continue;
            }

            // 发送JSON数据给服务器
            ret = send(sock, buf, strlen(buf), 0);
            if (ret == -1) {
                perror("send");
                free(buf);
                cJSON_Delete(json);
                continue;
            }
            free(buf);
            cJSON_Delete(json);

            char dest[100] = {0};
            // 接收服务器响应
            ret = recv(sock, dest, sizeof(dest) - 1, 0);
            if (ret == -1) {
                perror("recv");
                continue;
            }
            dest[ret] = '\0';
            puts(dest);

            cJSON *json1 = cJSON_Parse(dest);
            if (json1 == NULL) {
                printf("解析服务器响应JSON失败\n");
                continue;
            }

            cJSON *node = cJSON_GetObjectItem(json1, "type");  // 确保和发送的字段对应
            if (node == NULL) {
                printf("在服务器响应中找不到type字段\n");
                cJSON_Delete(json1);
                continue;
            }
            if (node->type == cJSON_String) {
                strcpy(type, node->valuestring);
            }

            node = cJSON_GetObjectItem(json1, "res");
            if (node == NULL) {
                printf("在服务器响应中找不到res字段\n");
                cJSON_Delete(json1);
                continue;
            }
            if (node->type == cJSON_Number) {
                int res = node->valueint;
                printf("结果值: %d\n", res);
            }
            cJSON_Delete(json1);

            sleep(3);
        }
    }

    close(sock);
    return 0;
}